﻿using AutoMapper;
using ManagementApi.Authorizers;
using ManagementApi.Models;
using ManagementApi.Models.Project;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Modules;
using Modules.Constructor;
using Modules.Corp;
using Modules.Project;
using Modules.Project.Entitys;
using PmSoft.ApplicationContext;
using PmSoft.Exceptions;
using static Modules.Project.ProjectConstants;

namespace ManagementApi.Controllers.ManagerPannel
{
    /// <summary>
    /// 项目管理员-项目相关接口
    /// </summary>
    [Route("/api/v1/manager/project")]
    [ApiController]
    [Authorize(Roles = "Manager")]
    public class ProjectController : ControllerBase
    {
        private readonly ProjectService projectService;
        private readonly CorpService corpService;
        public readonly ConstructorService constructorService;
        private readonly ProjectUpdateApplyService projectUpdateApplyService;
        private readonly IApplicationContext applicationContext;
        private readonly IMapper mapper;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ProjectController(ProjectService projectService,
            IApplicationContext applicationContext,
            ProjectUpdateApplyService projectUpdateApplyService,
            IMapper mapper,
            CorpService corpService,
            ConstructorService constructorService)
        {
            this.projectService = projectService;
            this.applicationContext = applicationContext;
            this.mapper = mapper;
            this.projectUpdateApplyService = projectUpdateApplyService;
            this.corpService = corpService;
            this.constructorService = constructorService;
        }

        #region 项目

        /// <summary>
        /// author:hzj date:2023/12/08 describe:项目登记 update: 2024 1/27 修改新增接口
        /// </summary>
        /// <param name="projectCheckInForm"></param>
        /// <returns></returns>
        [HttpPost("create_project")]
        public ApiResult CreateProject(ProjectRegisterForm projectCheckInForm)
        {
            var managerInfo = applicationContext.CurrentUser as ManagerInfo;
            ProjectInfo projectInfo = new();
            mapper.Map(projectCheckInForm, projectInfo);
            projectInfo.CreateTime = DateTime.Now;
            projectInfo.AuditStatus = 项目审核状态.待审核;
            projectInfo.PrjStatus = 项目状态.在建;
            projectInfo.IsRegister = true;
            projectInfo.DataSource = 项目数据来源.手动新增;
            projectInfo.NeedCompletData = false;
            projectInfo.ManagerId = managerInfo?.ManagerId;
            projectInfo.CreateManagerId = managerInfo?.ManagerId;
            var numSerialNum = projectService.GetProjectNumAndSerialNumber(projectInfo.AreaCode);
            projectInfo.PrjNum = numSerialNum.ProjectNum;
            projectInfo.SerialNumber = numSerialNum.SerialNumber;

            var supervisorCorp = corpService.GetCorpInfo(projectInfo.SupervisorCorpId ?? 0) ?? new()
            {
                Name = projectCheckInForm.SupervisorCorpName ?? string.Empty,
                Code = projectCheckInForm.SupervisorCorpCode ?? string.Empty,
                Type = ConstructorType.企业,
                CorpType = 企业分类.工程监理
            }; ;

            List<ProjectAttachment> projectAttachments = new();

            foreach (var item in projectCheckInForm.Attachments)
            {
                projectAttachments.Add(new ProjectAttachment()
                {
                    Id = Guid.NewGuid().ToString().Replace("-", ""),
                    AttachmentId = item,
                    ObjectId = projectInfo.ProjectId.ToString(),
                    Tenant = 项目附件租户.Project,
                    AttachmentType = 附件类型.中标通知书,
                    CreateTime = DateTime.Now
                });
            }

            if (!projectCheckInForm.HasSupervisor)
            {
                foreach (var item in projectCheckInForm.NoSupervisorAttachments)
                {
                    projectAttachments.Add(new ProjectAttachment()
                    {
                        Id = Guid.NewGuid().ToString().Replace("-", ""),
                        AttachmentId = item,
                        ObjectId = projectInfo.ProjectId.ToString(),
                        Tenant = 项目附件租户.Project,
                        AttachmentType = 附件类型.无监理证明,
                        CreateTime = DateTime.Now
                    });
                }
            }
            if (projectInfo.PositionCount > 1)
            {
                foreach (var item in projectCheckInForm.PositionAttachments)
                {
                    projectAttachments.Add(new ProjectAttachment()
                    {
                        Id = Guid.NewGuid().ToString().Replace("-", ""),
                        AttachmentId = item,
                        ObjectId = projectInfo.ProjectId.ToString(),
                        Tenant = 项目附件租户.Project,
                        AttachmentType = 附件类型.多地施工证明,
                        CreateTime = DateTime.Now
                    });
                }
            }
            if (projectInfo.HasEarnestMoney.HasValue && projectInfo.HasEarnestMoney.Value)
            {
                foreach (var item in projectCheckInForm.EarnestAttachments)
                {
                    projectAttachments.Add(new ProjectAttachment()
                    {
                        Id = Guid.NewGuid().ToString().Replace("-", ""),
                        AttachmentId = item,
                        ObjectId = projectInfo.ProjectId.ToString(),
                        Tenant = 项目附件租户.Project,
                        AttachmentType = 附件类型.担保文件,
                        CreateTime = DateTime.Now
                    });
                }
            }
            else
            {
                projectInfo.HasEarnestMoney = false;
                projectInfo.EarnestEndDate = null;
                projectInfo.EarnestMoney = 0;
                projectInfo.EarnestStartDate = null;
                projectInfo.EarnestUnitCode = null;
                projectInfo.EarnestUnitName = null;
            }
            projectService.UpdateProjectInfo(projectInfo, supervisorCorp, projectCheckInForm.SupervisorCorpAmount ?? 0, projectCheckInForm.CommanderId, projectAttachments);
            return ApiResult.Success("创建成功");
        }

        /// <summary>
        /// author:hzj date:2023/12/08 describe:修改项目 update: 2024 1/27 修改编辑接口
        /// </summary>
        /// <param name="projectId"></param>
        /// <param name="projectCheckInForm"></param>
        /// <returns></returns>
        [HttpPut("update_project/{projectId}")]
        public ApiResult UpdateProject(int projectId, ProjectRegisterForm projectCheckInForm)
        {
            #region 验证数据权限

            if (applicationContext.CurrentUser == null) throw new BusinessException("登录信息不存在");
            var projects = applicationContext.GetService<ProjectService>().GetProjectInfosByManagerId(applicationContext.CurrentUser.Id);
            if (!projects.Any(s => s.ProjectId == projectId)) throw new OwnAuthorizationFailedException();

            #endregion 验证数据权限

            //判断项目状态
            var projectInfo = projectService.GetProjectInfo(projectId);
            if (projectInfo == null)
                return ApiResult.Failure("项目数据不存在");
            if (projectInfo.AuditStatus == 项目审核状态.通过)
                return ApiResult.Failure("已审核项目不允许编辑");
            mapper.Map(projectCheckInForm, projectInfo);

            var supervisorCorp = corpService.GetCorpInfo(projectInfo.SupervisorCorpId ?? 0) ?? new CorpInfo()
            {
                Name = projectCheckInForm.SupervisorCorpName ?? string.Empty,
                Code = projectCheckInForm.SupervisorCorpCode ?? string.Empty,
                Type = ConstructorType.企业,
                CorpType = 企业分类.工程监理
            };

            List<ProjectAttachment> projectAttachments = new();

            foreach (var item in projectCheckInForm.Attachments)
            {
                projectAttachments.Add(new ProjectAttachment()
                {
                    Id = Guid.NewGuid().ToString().Replace("-", ""),
                    AttachmentId = item,
                    ObjectId = projectInfo.ProjectId.ToString(),
                    Tenant = 项目附件租户.Project,
                    AttachmentType = 附件类型.中标通知书,
                    CreateTime = DateTime.Now
                });
            }

            if (!projectCheckInForm.HasSupervisor)
            {
                foreach (var item in projectCheckInForm.NoSupervisorAttachments)
                {
                    projectAttachments.Add(new ProjectAttachment()
                    {
                        Id = Guid.NewGuid().ToString().Replace("-", ""),
                        AttachmentId = item,
                        ObjectId = projectInfo.ProjectId.ToString(),
                        Tenant = 项目附件租户.Project,
                        AttachmentType = 附件类型.无监理证明,
                        CreateTime = DateTime.Now
                    });
                }
            }
            if (projectInfo.PositionCount > 1)
            {
                foreach (var item in projectCheckInForm.PositionAttachments)
                {
                    projectAttachments.Add(new ProjectAttachment()
                    {
                        Id = Guid.NewGuid().ToString().Replace("-", ""),
                        AttachmentId = item,
                        ObjectId = projectInfo.ProjectId.ToString(),
                        Tenant = 项目附件租户.Project,
                        AttachmentType = 附件类型.多地施工证明,
                        CreateTime = DateTime.Now
                    });
                }
            }
            if (projectInfo.HasEarnestMoney.HasValue && projectInfo.HasEarnestMoney.Value)
            {
                foreach (var item in projectCheckInForm.EarnestAttachments)
                {
                    projectAttachments.Add(new ProjectAttachment()
                    {
                        Id = Guid.NewGuid().ToString().Replace("-", ""),
                        AttachmentId = item,
                        ObjectId = projectInfo.ProjectId.ToString(),
                        Tenant = 项目附件租户.Project,
                        AttachmentType = 附件类型.担保文件,
                        CreateTime = DateTime.Now
                    });
                }
            }
            else
            {
                projectInfo.HasEarnestMoney = false;
                projectInfo.EarnestEndDate = null;
                projectInfo.EarnestMoney = 0;
                projectInfo.EarnestStartDate = null;
                projectInfo.EarnestUnitCode = null;
                projectInfo.EarnestUnitName = null;
            }
            if (projectInfo.AuditStatus == 项目审核状态.不通过)
            {
                projectInfo.AuditStatus = 项目审核状态.待审核;
            }
            projectService.UpdateProjectInfo(projectInfo, supervisorCorp, projectCheckInForm.SupervisorCorpAmount ?? 0, projectCheckInForm.CommanderId, projectAttachments);
            return ApiResult.Success("修改成功");
        }

        /// <summary>
        /// author:hzj date:2024/3/12 describe:完善信息（仅主管登记和平台同步需要完善信息）
        /// </summary>
        /// <param name="id"></param>
        /// <param name="form"></param>
        /// <returns></returns>
        [HttpPut("complet_project/{id}")]
        public ApiResult CompletProjectInfo(int id, ProjectCompletForm form)
        {
            ProjectInfo? projectInfo = projectService.GetProjectInfo(id) ?? throw new BusinessException("项目信息不存在");
            projectInfo.IsBuilderLicence = true;
            projectInfo.BuilderLicences = form.BuilderLicences;
            projectInfo.BuilderLicencesGrantDate = form.BuilderLicencesGrantDate;
            projectInfo.BuilderLicencesTermDate = form.BuilderLicencesTermDate;
            projectInfo.HasEarnestMoney = form.HasEarnestMoney;
            if (form.HasEarnestMoney)
            {
                projectInfo.EarnestUnitName = form.EarnestUnitName;
                projectInfo.EarnestUnitCode = form.EarnestUnitCode;
                projectInfo.EarnestStartDate = form.EarnestStartDate;
                projectInfo.EarnestEndDate = form.EarnestEndDate;
                projectInfo.EarnestMoney = form.EarnestMoney;
            }
            else
            {
                form.EarnestAttachments = null;
                projectInfo.EarnestUnitName = null;
                projectInfo.EarnestUnitCode = null;
                projectInfo.EarnestStartDate = null;
                projectInfo.EarnestEndDate = null;
                projectInfo.EarnestMoney = null;
            }
            projectService.CompletProjectInfo(projectInfo, form.EarnestAttachments);
            return ApiResult.Success("完善成功");
        }

        /// <summary>
        /// 获取完善信息表单数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        /// <exception cref="BusinessException"></exception>
        [HttpGet("complet_project/{id}/form")]
        public ApiResult<ProjectCompletForm> GetCompletProjectInfo(int id)
        {
            ProjectInfo? projectInfo = projectService.GetProjectInfo(id) ?? throw new BusinessException("项目信息不存在");
            return ApiResult<ProjectCompletForm>.Success(projectInfo.AsCompletForm(applicationContext));
        }

        /// <summary>
        /// author:hzj date:2023/12/08 describe:项目分页
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("project_page")]
        public ApiResult<PageDto<ProjectInfoDto>> GetProjects([FromQuery] ProjectInfoQuery query, int pageIndex = 1, int pageSize = 20)
        {
            query.ManagerId = applicationContext.CurrentUser?.Id;
            var pageDto = projectService.GetProjectInfos(query, pageIndex, pageSize).AsPageDto(m => m.AsDto(applicationContext));
            return ApiResult<PageDto<ProjectInfoDto>>.Success(pageDto);
        }

        /// <summary>
        /// author:hzj date:2023/12/08 describe:获取详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("detail/{id}")]
        public ApiResult<ProjectInfoDto> GetProjectInfo(int id)
        {
            var info = projectService.GetProjectInfo(id);
            if (info == null) return ApiResult<ProjectInfoDto>.Failure("不存在该项目");
            ProjectInfoDto projectInfoDto = info.AsDto(applicationContext);
            return ApiResult<ProjectInfoDto>.Success(projectInfoDto);
        }

        /// <summary>
        /// author:hzj date:2023/12/08 describe:获取详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("base_info/{id}")]
        public ApiResult<ProjectBaseInfo> GetProjectBaseInfo(int id)
        {
            var info = projectService.GetProjectInfo(id);
            if (info == null) return ApiResult<ProjectBaseInfo>.Failure("不存在该项目");
            return ApiResult<ProjectBaseInfo>.Success(info.AsBaseInfo(applicationContext));
        }

        /// <summary>
        /// author:hzj date:2023/12/08 describe:删除项目
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpDelete("delete/{id}")]
        public ApiResult DeleteProject(int id)
        {
            #region 验证数据权限

            if (applicationContext.CurrentUser == null) throw new BusinessException("登录信息不存在");
            var projects = applicationContext.GetService<ProjectService>().GetProjectInfosByManagerId(applicationContext.CurrentUser.Id);
            if (!projects.Any(s => s.ProjectId == id)) throw new OwnAuthorizationFailedException();

            #endregion 验证数据权限

            var info = projectService.GetProjectInfo(id);
            if (info == null)
                return ApiResult.Failure("项目数据不存在");
            if (info.AuditStatus == 项目审核状态.通过)
                return ApiResult.Failure("已审核项目不允许删除");
            projectService.Delete(id);
            return ApiResult.Success("删除成功");
        }

        /// <summary>
        /// author:hzj date:2023/12/08 describe:项目表单数据
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        [HttpGet("{id}/projectform")]
        public ApiResult<ProjectRegisterForm> GetProject(int id)
        {
            var data = projectService.GetProjectInfo(id);
            if (data == null)
                return ApiResult<ProjectRegisterForm>.Failure("项目数据不存在");
            return ApiResult<ProjectRegisterForm>.Success(data.AsForm(applicationContext));
        }

        /// <summary>
        /// author:hzj date:2023/12/08 describe:项目下拉
        /// </summary>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        [HttpGet("pulldown")]
        public ApiResult<PageDto<LabelValue<int>>> GetPulldown([FromQuery] ProjectInfoQuery query, int pageIndex = 1, int pageSize = 9999)
        {
            query.ManagerId = applicationContext.CurrentUser?.Id;
            query.AuditStatus = 项目审核状态.通过;
            var pageDto = projectService.GetProjectInfosByManagerId(query, pageIndex, pageSize);
            var dtos = pageDto.AsPageDto(source => { return source.AsPullDownDto(); });
            return ApiResult<PageDto<LabelValue<int>>>.Success(dtos);
        }

        /// <summary>
        /// 是否存在修改申请
        /// </summary>
        /// <returns></returns>
        [HttpGet("exists_update_apply/{projectId}")]
        public ApiResult<bool> ExistsByPrjId(int projectId)
        {
            return ApiResult<bool>.Success(projectUpdateApplyService.ExistsByPrjIdNoAudit(projectId));
        }

        /// <summary>
        /// 修改申请
        /// </summary>
        /// <returns></returns>
        [HttpPost("update_apply/{projectId}")]
        public ApiResult CreateUpdateProjectApply(int projectId, ProjectUpdateApplyForm form)
        {
            #region 验证数据权限

            if (applicationContext.CurrentUser == null) throw new BusinessException("登录信息不存在");
            var projects = applicationContext.GetService<ProjectService>().GetProjectInfosByManagerId(applicationContext.CurrentUser.Id);
            if (!projects.Any(s => s.ProjectId == projectId)) throw new OwnAuthorizationFailedException();

            #endregion 验证数据权限

            if (projectUpdateApplyService.ExistsByPrjIdNoAudit(projectId)) return ApiResult.Failure("已提交过修改申请");
            var project = projectService.GetProjectInfo(projectId);
            if (project == null) return ApiResult.Failure("未查询到项目信息");
            if (project.AuditStatus != 项目审核状态.通过) return ApiResult.Failure("未审核通过项目不允许提交申请");
            ProjectUpdateApply projectUpdateApply = new();
            mapper.Map(form, projectUpdateApply);
            projectUpdateApply.ProjectId = projectId;
            projectUpdateApplyService.Create(projectUpdateApply, form.Attachments);
            return ApiResult.Success("申请成功");
        }

        #endregion 项目
    }
}